<template>
  <Fragment>
    <template v-for="(item, index) in data">
      <el-tooltip :key="item.id" class="item" effect="dark" placement="top">
        <div slot="content">
          {{item.taskName}}<br />
          任务名：{{item.startTime}}<br />
          结束时间：{{item.endTime}}天<br />
          结束时间：{{item.endTime}}天<br />
          持续时间：{{item.totalTime}}天<br />
          负责人：{{item.personInCharges.join(',')}}<br />
          完成进度：{{item.actual_process * 100}}%<br />
          <span class="inline_highlight">前置任务：{{getPreTask(item, '无')}}<br /></span>
        </div>
        <tr class="mouse_hover">
          <!-- el-icon-circle-plus -->
          <td :style="{
            paddingLeft: item.grade * 15 + 'px',
            fontWeight: item.children.length ? 'bold' : 500,
            }">
            <span v-if="item.children.length" :class="!hideList[item.id] ? 'icon_type el-icon-folder-opened' : 'icon_type el-icon-folder'" @click="tolgger(item.id)"></span>
            <span v-else class="icon_type el-icon-document"></span>
            {{item.taskName}}
          </td>
          <td>{{item.startTime}}</td>
          <td>{{item.endTime}}</td>
          <td>{{ total_time(item.startTime, item.endTime) }}</td>
          <td>{{item.personInCharges.join(',')}}</td>
          <!-- <td>{{getPreTask(item)}}</td> -->
          <td @click="item.children.length === 0 ? progressEditShow(item) : () =>{}" class="edit_process">{{item.actual_process * 100}}%
            <span v-if="item.children.length === 0" style="color: #67c23a;font-size: 14px;">#</span>
          </td>
          <td><span class="icon_add el-icon-plus" @click="addShow(item)" /></td>
        </tr>
      </el-tooltip>
      <template v-if="item.children.length && hideList[item.id] !== true">
        <GanttRow :data="item.children" :key="'children' + item.id + index " :listChange="listChange" :editProcess="editProcess" :addItem="addItem" />
      </template>
    </template>
    <!-- 子任务添加 -->
    <el-dialog title="添加子任务" :visible.sync="addDialogTableVisible" width="50%">
      <el-form :model="itemData" :rules="rules">
        <el-form-item label="子任务名" :label-width="labelWidth" :rules="rules.taskName">
          <el-input v-model="itemData.taskName" style="width:80%" placeholder="请输入任务名"></el-input>
        </el-form-item>
        <div :style="{paddingLeft: labelWidth}">
          <span style="color: #e6a23c;font-size: 13px!important;">父任务：{{parentTime.startTime}} &nbsp;——&nbsp;{{parentTime.endTime}}</span><br />
          <span style="color: #e6a23c;font-size: 13px!important;">子任务：{{timeRange(children, ' &nbsp;——&nbsp;')}}</span>
        </div>
        <el-form-item label="任务周期" :label-width="labelWidth" :rules="rules.date">
          <el-date-picker v-model="dates" value-format="yyyy-MM-dd" type="daterange" align="right" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="dateChange">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="时间冲突" :label-width="labelWidth">
          <el-switch v-model="conflict" @change="dates = []; itemData.startTime = ''; itemData.endTime = ''" active-text="禁止" inactive-text="允许" />
        </el-form-item>
        <el-form-item label="持续时间" :label-width="labelWidth">
          <el-input v-model="itemData.totalTime" style="width:120px" :disabled="true">
            <template slot="append">天</template>
          </el-input>
        </el-form-item>
        <el-form-item label="负责人" :label-width="labelWidth" :rules="rules.personInCharges">
          <el-input :value="itemData.personInCharges.join(' ')" @input="userInput" style="width:80%" placeholder="姓名用空格分隔"></el-input>
        </el-form-item>
        <el-form-item v-if="isShowPredecessorsOptions" label="前置任务" :label-width="labelWidth">
          <el-select v-model="itemData.predecessors" placeholder="请选择">
            <el-option v-for="item in predecessorsOptions" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-select>
          <span class="weight_info">前置任务完成后才可开始本任务</span>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancelAdd">取 消</el-button>
        <el-button type="primary" @click="add">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 实际进度修改 -->
    <el-dialog title="任务进度修改" :visible.sync="processDialogVisible" width="40%">
      <p class="process_info">
        <span>预期进度：</span>
        <el-progress :text-inside="true" :stroke-width="26" :percentage="currentProcess(itemData.startTime, itemData.totalTime)  * 100 || 0"></el-progress>
      </p>
      <p class="process_info">
        <span>实际进度：</span> <span class="process_back">{{process_text}}</span>
        <el-progress :text-inside="true" :stroke-width="24" :percentage="itemData.actual_process * 100" :status="projectStatus(currentProcess(itemData.startTime, itemData.totalTime), itemData.actual_process)"></el-progress>
      </p>
      <el-input-number size="small" :precision="2" :step="0.05" v-model="itemData.actual_process" :min="0" :max="1"></el-input-number>
      <p>
        <span style="display: block; margin: 10px 0;">完成进度说明：</span>
        <el-input type="textarea" :rows="2" v-model="notes" placeholder="请输入完成的进度说明" />
      </p>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelEdit">取 消</el-button>
        <el-button type="primary" @click="progressEdit">确 定</el-button>
      </span>
    </el-dialog>
  </Fragment>
</template>

<script>
import GanttRow from '@/components/GanttRow';
import { total_time, currentProcess, dataCopy, getFormatDate, projectStatus } from '@/utils/GanttUtil'
function initData() {
  return JSON.parse(JSON.stringify({
    id: '',
    taskName: '',
    startTime: '',
    endTime: '',
    totalTime: 0,
    personInCharges: [],
    parentId: '',
    rootId: '',
    grade: -1,
    actual_process: 0,
    children: [],
    predecessors: '',
  }))
}
export default {
  name: 'GanttRow',
  data() {
    return {
      projectStatus,
      hideList: {},
      addDialogTableVisible: false,
      itemData: initData(),
      dates: [],
      labelWidth: '80px',
      rules: {
        taskName: [{ required: true }],
        personInCharges: [{ required: true }],
        date: [{ required: true }]
      },
      parentTime: {},
      processDialogVisible: false,
      total_time,
      currentProcess,
      notes: '',
      process_notes: 0,
      children: [],
      conflict: true, // 是否允许冲突
      predecessorsOptions: [], // 前置任务选择菜单
      isShowPredecessorsOptions: true,
      // 获取前置任务名
      getPreTask(item, label = '') {
        const targetNode = this.data.find(ele => ele.id === item.predecessors);
        return targetNode?.taskName || label;
      }
    }
  },
  props: {
    data: {
      type: Array,
      default: () => []
    },
    listChange: { // 展开 / 关闭 列表
      type: Function,
      default: (id) => console.log(id)
    },
    addItem: {
      type: Function,
      default: () => { }
    },
    editProcess: {
      type: Function,
      default: () => { }
    }
  },
  components: {
    GanttRow,
  },
  computed: {
    process_text() {
      if (this.itemData.actual_process < this.process_notes) return '*当前项目进度后退，请确认是否无误';
      return '';
    }
  },
  methods: {
    // 时间范围
    timeRange(children, type) {
      if (!children.length) return
      // 将开始时间和结束时间取出返回 , 然后再展开数组
      const arr = children.map(item => [new Date(item.startTime).getTime(), new Date(item.endTime).getTime()]).flat(2);
      const max = getFormatDate(Math.max(...arr));
      const min = getFormatDate(Math.min(...arr));
      return min + type + max;
    },
    tolgger(id) {
      // console.log(!!this.hideList[id]);
      this.hideList[id] = !this.hideList[id];
      this.$forceUpdate();
      this.listChange(id);
    },
    // 显示添加子任务
    addShow(item) {
      this.addDialogTableVisible = true;
      this.itemData.rootId = item.rootId;
      this.itemData.parentId = item.id;
      this.itemData.grade = item.grade + 1;
      this.parentTime = { startTime: item.startTime, endTime: item.endTime };
      this.predecessorsOptions = item.children.map(item2 => ({label: item2.taskName, value: item2.id}));
      this.children = dataCopy(item.children);
    },
    // 添加函数
    add() {
      // 去除空格
      this.itemData.personInCharges = this.itemData.personInCharges.filter(item => item != '');
      if (this.itemData.taskName.trim() == '') return this.$message({ message: '子任务名不能为空', type: 'warning' });
      if (this.itemData.startTime.trim() == '') return this.$message({ message: '开始/结束时间不能为空', type: 'warning' });
      if (this.itemData.personInCharges.length === 0) return this.$message({ message: '至少有一个人负责任务', type: 'warning' });
      this.addItem(this.itemData);
      this.cancelAdd();
    },
    // 取消添加
    cancelAdd() {
      this.addDialogTableVisible = false;
      this.itemData = initData();
      this.dates = [];
      this.predecessorsOptions = [];
    },
    // 日期变化时
    dateChange() {
      if (!this.dates) {
        this.itemData.startTime = '';
        this.itemData.endTime = '';
        return;
      }
      const selfStartDate = new Date(this.dates[0]).getTime();
      // console.log(this.children.some(item => new Date(item.endTime).getTime() > selfStartDate));
      // 判断子任务与父任务
      let timeRangecheck = this.timeRangecheck({ startTime: this.dates[0], endTime: this.dates[1] });
      if (timeRangecheck) {
        this.dates = [];
        return this.$message({ message: timeRangecheck, type: 'warning' });
      }
      // console.log(this.conflict && this.children.some(item => new Date(item.endTime).getTime() > selfStartDate));
      if (this.conflict && this.children.some(item => new Date(item.endTime).getTime() > selfStartDate)) {
        this.$message({ message: '子任务时间不能重叠', type: 'warning' });
        this.dates = [];
        return;
      }
      this.itemData.startTime = this.dates[0];
      this.itemData.endTime = this.dates[1];
      this.itemData.totalTime = this.total_time(this.dates[0], this.dates[1]);
    },
    // 添加负责人
    userInput(item) {
      // console.log(item);
      this.itemData.personInCharges = item.replace(/ +/g, ' ').split(' ');
      // console.log(this.itemData.personInCharges);
    },
    // 校验时间不能大于父项目的时间
    timeRangecheck(self) {
      if (new Date(this.parentTime.startTime) > new Date(self.startTime)) return '子任务的开始时间不能小于父任务的开始时间';
      if (new Date(this.parentTime.endTime) < new Date(self.endTime)) return '子任务的结束时间不能大于父任务的结束时间';
      return '';
    },
    // 进度修改
    progressEditShow(item) {
      // console.log(item.predecessors);
      const targetNode = this.data.find(ele => ele.id === item.predecessors);
      // 如果有目标节点，且节点 actual_process !== 1
      if (!!targetNode && targetNode?.actual_process !== 1) return this.$message({ message: '需要先完成前置任务才可修改任务进度', type: 'warning' });
      this.processDialogVisible = true
      this.itemData = dataCopy(item);
      this.process_notes = dataCopy(item.actual_process);
    },
    // 确定修改
    progressEdit() {
      if (this.notes.trim() === '') return this.$message({ message: '完成的进度说明不能为空', type: 'warning' });
      const { actual_process, id, rootId } = this.itemData;
      this.editProcess({ actual_process, id, rootId }, this.notes);
      this.cancelEdit()
    },
    // 取消修改
    cancelEdit() {
      this.processDialogVisible = false;
      this.itemData = initData();
      this.notes = ''
    },
    
  }
}
</script>

<style lang="scss">
.edit_process {
  cursor: pointer;
}
.process_info {
  margin-bottom: 10px;
  span {
    display: inline-block;
    margin-bottom: 5px;
  }
}
.process_back {
  font-size: 12px;
  color: #f56c6c;
}
.weight_info {
  margin-left: 10px;
  color: #f56c6c;
  font-size: 12px;
}
.inline_highlight {
  display: inline-block;
  background-color: #fff;
  padding: 2px;
  color: #222;
  margin-top: 2px;
  font-weight: bold;
  border-radius: 2px;
}
</style>